//  1.数组的解构赋值

//1.1 基本使用 变量的取值由数组的元素的位置决定
let [a, b, c] = [1, 2, 3];  // a=1 b=2 c=3

//1.2 解构不成功undefined 
let [a1] = [] // a1: undefined

//1.3 报错: 等号右边的值 本身或者转化为对象后不具备Iterator 接口
// let [a2] = 1 // TypeError: 1 is not iterable (false null undefined number NaN)
// let [a3] = {} // TypeError: {} is not iterable

//1.4 默认值 只有当一个数组成员严格等于undefined，默认值才会生效。
let [a4, a5 = 'b'] = ['a', undefined]; // a4='a', a5='b'

  //1.4.1 为表达式 惰性求值
  function fn() {
    console.log('aaa');
  }
  let [a6 = fn()] = [null] // a6 = null
  // i能取到值，所以函数fn根本不会执行。上面的代码其实等价于下面的代码
  // let a6;
  // const target = [null][0]
  // a6 = target === undefined ? fn() : target

  // 1.4.2 默认值可以引用解构赋值的其他变量，但该变量必须已经声明。
  let [a7 = 1, a8 = a7] = [2];    // a7=2; a8=2
  // let [a9 = a10, a10 = 1] = [];     // ReferenceError: a10 is not defined  a9用a10做默认值时，a10还没有声明。



//  2.对象的解构赋值 变量的取值由对象的属性名决定

// 2.1基本使用
let { b1, b2 } = { b1: 'a', b2: 'b' } // b1='a' b2='b'

// 2.2量名与属性名不一致
let { b3: b4 } = { b3: 'a' } // b3 is not defined  b4 'a'
// let { b } = {b: 'b'} 是 let { b: b } = {b: 'b'} 
// 真正赋值的是b4，而不是b3

// 2.3子对象所在的父属性不存在，那么将会报错。
// let { b5: { b6 } } = { b7: 1 } // Cannot read property 'b6' of undefined b5为undefined undefined里取b6，报错
let { b8: { b9 } } = { b8: 1 } // b9 undefined  1里面取b9

// 2.4对象的解构赋值可以取到继承的属性。
const b10 = {}
const b11 = { b12: '12' }
Object.setPrototypeOf(b10, b11);
const { b12 } = b10; // b12 = 12 b10的原型对象是b11。b12是继承自b11的属性

// 2.5默认值 默认值生效的条件是，对象的属性值严格等于undefined。
const { b13 = 3 } = { b13: null };  // b13 = null

//2.5.1数组本质是特殊的对象，对数组进行对象属性的解构。
let arr = [1, 2, 3];
let { 0: b14, [arr.length - 1]: b15 } = arr; // b14=1 b15=3



// 3.字符串的解构赋值 字符串被转换成类似数组的对象
const [c1,c2,c3] = 'abc' // c1='a' c2='b' c3='c'


// 4.数值和布尔值的解构赋值
// 只要等号右边的值不是对象或数组，就先将其转为对象
let { toString: d1 } = 123;
d1 === Number.prototype.toString // true
let { toString: d2 } = true;
d2 === Boolean.prototype.toString // true

// 5.null和undefined的解构赋值
// undefined和null无法转为对象，所以对它们进行解构赋值，都会报错。
// let { e1: e2 } = null   // Cannot destructure property 'e1' of 'null' as it is null.
// let { e3: e4 } = undefined // Cannot destructure property 'e3' of 'undefined' as it is undefined.

// 6.用途
// 6.1交换变量
let f1 = 1;
let f2 = 2;
[f1, f2] = [f2, f1]; // f1=2 f2=1
// 6.2提取json数据
let f3 = {
  f4: 4,
  f5: 5
} 
const {f4, f5} = f3 // f4 = 4 f5 = 5
// 6.3默认值
const f6 = {
  f7: undefined
}
const {f7 = 7} = f6 // f7=7
// 6.4遍历map结构
const map = new Map()
map.set('f8', 8)
map.set('f9', 9)
for (let [key, value] of map) {
  console.log(key, value) // 'f8' 8    'f9' 9
}
// 6.5输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map")